//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#ifndef __ELASTOS_VGA_H__
#define __ELASTOS_VGA_H__

// physical memory address base
#define VGA_TEXTMODE_MEMORY_PHYSBASE    0xb8000

// base port
#define VGA_ADDRESS_REGISTER            0x03d4
#define VGA_DATA_REGISTER               0x03d5

// CRT Controller Registers' index
#define CURSOR_MAXIMUM_SCANLINE         0x09
#define CURSOR_SCANLINE_START           0x0a
#define CURSOR_SCANLINE_END             0x0b
#define CURSOR_LOCATION_HIGH            0x0e
#define CURSOR_LOCATION_LOW             0x0f

#define TEXT_COLOR(bgcolor, fgcolor)    (((bgcolor) << 4) + (fgcolor))
#define TEXT_CHAR(value, color)         ((uint16_t)(((color) << 8) \
                                            + (uint8_t)(value)))

enum {
    TextColor_Black             = 0x0,
    TextColor_Blue              = 0x1,
    TextColor_Green             = 0x2,
    TextColor_Aqua              = 0x3,
    TextColor_Red               = 0x4,
    TextColor_Purple            = 0x5,
    TextColor_Yellow            = 0x6,
    TextColor_White             = 0x7,
    TextColor_Gray              = 0x8,
    TextColor_LightBlue         = 0x9,
    TextColor_LightGreen        = 0xa,
    TextColor_LightAqua         = 0xb,
    TextColor_LightRed          = 0xc,
    TextColor_LightPurple       = 0xd,
    TextColor_LightYellow       = 0xe,
    TextColor_BrightWhite       = 0xf,
};

class Video : public CDeviceDriver
{
public:
    CARAPI Read(
        /* [in] */ Int64 u64Offset,
        /* [in] */ Int32 bytesToRead,
        /* [out] */ MemoryBuf * pBuffer,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Write(
        /* [in] */ Int64 u64Offset,
        /* [in] */ const MemoryBuf & buffer,
        /* [out] */ Int32 * pBytesWritten,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Control(
        /* [in] */ Handle32 nControlCode,
        /* [in] */ const MemoryBuf & inBuffer,
        /* [out] */ MemoryBuf * pOutBuffer,
        /* [out] */ IEvent * * ppCompletionEvent);

    virtual void Dispose() {}

    Video()
    {
        m_pTextChars = (uint16_t *)VIRTADDR(VGA_TEXTMODE_MEMORY_PHYSBASE);
        m_uCursorLocation = 0;
        m_uScreenColumns = 80;
        m_uScreenRows = 25;
        m_bDefaultTextColor = TEXT_COLOR(TextColor_Black, TextColor_White);
    }

public:
    uint16_t            *m_pTextChars;

    // Next character, this address will be cover.
    uint_t              m_uCursorLocation;

    uint32_t            m_uScreenColumns;
    uint32_t            m_uScreenRows;

    byte_t              m_bDefaultTextColor;
};

EXTERN IDeviceDriver * CDECL CreateVGA(uint_t uDeviceNo, void *pvParameter);

#endif // __ELASTOS_VGA_H__
